home *** CD-ROM | disk | FTP | other *** search
- title BREAKON
- comment \
- Function Ctrl-Brk terminates any program
- Author Robert Wagner
- Date Written 12/22/85
- Remarks Must the the last program in your AUTOEXEC.BAT
- When Ctrl-Brk is hit, does the following:
- ..makes sure you are not on the command line or
- in a resident program or executing a DOS call
- (a second Ctrl-Brk will bypass these checks).
- ..resets the keyboard
- ..discards all interrupts pending in the 8259
- ..resets 8255 and 8259 ports (61 and 21)
- ..does a BIOS break (1B) and a DOS break (23) to
- give your program's Ctrl-Brk routine a chance to do
- its thing.
- If I do not get control back, third Ctrl-Brk will
- bypass this step.
- ..restores all interrupt vectors to the values
- they had when I was made resident. That's
- why I have to be last in the AUTOEXEC.
- ..restores screen parameters in BIOS segment
- ..clears the screen (into BACKSCRL, if present)
- ..does not flush keyboard buffer. May help to
- indicate where it blew up.
- ..does a terminate (4C) with return code FF.
- \
- cseg segment
- assume cs:cseg,ds:cseg,es:nothing
- org 100H ; I am .COM
- start proc far
- jmp makeres
- start endp
-
- db 'BREAKON v1.1 Public Domain 1985 Robert Wagner, 806-763-3375'
- a_int09 dd 0 ; original INT 09
- a_int21 dd 0 ; original INT 21
- zero dd 0 ; addr of interrupt vectors
- port21 db 0 ; initial values in ports
- port61 db 0
- in_prog db 0 ; in-progress flag
- a_break dw 71H,40H ; addr of BIOS break bit
- a_bios dw 49H,40H ; addr of BIOS screen stuff
- BIOSwss db 30 dup(?) ; save area for above
- DOSregs dw 6 dup(?) ; save area for registers of last dos call
- ctrl_key equ 29
- scroll_key equ 70
- s_vector equ 512
-
-
- assume cs:cseg,ds:nothing,es:nothing
- int09 proc far ; comes here on keystroke
- sti
- push ax
- in al,60H ; read the keycode
- test al,10000000B ; ignore "key break"
- jnz int09x
- cmp al,ctrl_key ; ignore Ctrl key
- je int09x
- cmp al,scroll_key ; check for Brk
- je int09a
- mov cs:in_prog,0 ; some other key, reset in progress flag
- int09x: pop ax
- jmp dword ptr cs:a_int09 ; jump to original int09
-
- int09a: mov ah,2 ; check for Ctrl-Brk
- int 16H
- test al,00000100B
- jz int09x
- call bomb ; do it
- jmp int09x
- int09 endp
-
- assume cs:cseg,ds:cseg,es:nothing
-
- bomb proc near
- push ds
- push es
- push bx
- mov ax,cs
- mov ds,ax
-
- inc in_prog
- cmp in_prog,3 ; third try?
- je bombc ; y - bypass below tests, do it
- cmp in_prog,2 ; second try?
- je bomba ; y - bypass some of the tests
- mov bx,sp
- mov ax,word ptr ss:[bx+12] ; get segment of interrupted task
- mov bx,cs
- cmp ax,bx ; compare to mine
- jb bombx ; lower: resident pgm or DOS, exit
- cmp ax,0F000H ; BIOS call in progress?
- jae bombx ; y - exit
- bomba: mov ax,5100H ; get psp of current task
- int 21H
- mov es,bx
- cmp byte ptr es:[0],0CDH ; look like a program?
- jne bombx
- mov ax,es
- cmp ax,es:[16H] ; was it invoked by itself?
- jne bombc ; y - it's COMMAND.COM
- mov in_prog,0 ; get out
- bombx: pop bx
- pop es
- pop ds
- ret
-
- bombc: cld
- in al,61H ; reset the keyboard (via 8255)
- or al,10000000B
- out 61H,al
- mov al,port61 ; reset the 8255
- and al,01111111B
- out 61H,al
- cli
- mov al,port21 ; reset interrupts enabled (port 21)
- out 21H,al
- mov cx,8
- bomb1: mov al,20H ; cancel anything stacked in 8259
- out 20H,al
- loop bomb1
- sti
-
- cmp in_prog,3
- je bomb2
- les di,dword ptr a_break
- mov al,80H
- stosb ; set bios break bit
- int 1BH ; do an int1B (BIOS break function)
- mov ax,dosregs+00 ; load the registers from last int21
- mov bx,dosregs+02
- mov cx,dosregs+04
- mov dx,dosregs+06
- mov es,dosregs+08
- mov ds,dosregs+10
- int 23H ; do an int23 (DOS break function)
-
- bomb2: mov ax,cs
- mov ds,ax
- cld
- cli
- les di,zero ; restore interrupt vectors
- lea si,intvec
- mov cx,s_vector
- rep movsw
-
- les di,dword ptr a_bios ; restore screen stuff
- lea si,BIOSwss
- mov cx,size BIOSwss
- rep movsb
-
- les di,dword ptr a_break
- mov al,0
- stosb ; clear bios break bit
-
- sti
- mov al,0 ; clear the screen
- mov cx,0
- mov dx,(24*256)+79
- mov bh,7
- mov ah,6
- int 10H
- mov dx,0 ; cursor home
- mov bh,0
- mov ah,2
- int 10H
- mov in_prog,0
- mov ah,4CH ; end the process
- mov al,0FFH
- int 21H
- bomb endp
-
- int21 proc far ; comes here on int21
- assume cs:cseg,ds:nothing,es:nothing
- cmp cs:in_prog,0
- jne int21x
- mov cs:dosregs+00,ax ; save the registers
- mov cs:dosregs+02,bx
- mov cs:dosregs+04,cx
- mov cs:dosregs+06,dx
- mov cs:dosregs+08,es
- mov cs:dosregs+10,ds
- int21x: jmp dword ptr cs:a_int21
- int21 endp
-
- makeres proc near
- assume cs:cseg,ds:cseg,es:nothing
- mov ax,3509H ; get vector 09H
- int 21H
- mov word ptr a_int09,bx
- mov word ptr a_int09+2,es
-
- mov ax,2509H ; set vector 09H
- mov dx,offset int09
- int 21H
-
- mov ax,3521H ; get vector 21H
- int 21H
- mov word ptr a_int21,bx
- mov word ptr a_int21+2,es
-
- mov ax,2521H ; set vector 21H
- mov dx,offset int21
- int 21H
-
- in al,21H ; save port 21
- mov port21,al
- in al,61H ; save port 61
- mov port61,al
-
- mov ax,ds
- mov es,ax
-
- lds si,dword ptr cs:a_bios ; save screen stuff
- lea di,BIOSwss
- mov cx,size BIOSwss
- rep movsb
-
- lds si,cs:zero ; save interrupt vectors
- lea di,intvec
- mov cx,s_vector
- rep movsw
-
- mov ax,3100H ; ---- terminate and stay resident ----
- mov dx,offset intvec+s_vector+s_vector
- mov cl,4
- shr dx,cl ; should be able to write (the_end/16+1)
- inc dx
- int 21H
- makeres endp
-
- intvec label word ; stores original int vectors here
-
- cseg ends
- end start